/**
 * Account.java 2008-05-12
 * 
 * Linker is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package linker.account;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;

/**
 * The connection class supports your login, disconnecting and getting
 * XMPPConnection
 * 
 * This class is to manage the connecting process, which includes login,
 * disconnecting and getting the original XMPPConnection.
 * 
 * @version 2008-05-16
 * @author Jianfeng tujf.cn@gmail.com
 * @author AwakenRz awakenrz@gmail.com
 * 
 */

public final class Connect {

	/**
	 * The default constructor.
	 */
	private Connect() {
	}

	/**
	 * The XMPPConnection.
	 */
	private static XMPPConnection connection;

	/**
	 * The flag record whether the connect procedure is canceled or not.
	 */
	private static boolean canceled = false;

	/**
	 * The port used for xmpp connect.
	 */
	private static final int XMPPPORT = 5222;

	/**
	 * @return The used XMPPConnection.
	 */
	public static XMPPConnection getConnecdtion() {
		return connection;
	}

	/**
	 * The login progress.
	 * 
	 * @param progress
	 *            The LoginProgress refer
	 * @param username
	 *            User name.
	 * @param password
	 *            password.
	 * @param host
	 *            The host of the server.
	 * @param portStr
	 *            The string of the port number.
	 * @param domain
	 *            The domain of the server.
	 * @return Whether connection success or not.
	 */
	public static boolean login(final LoginProgress progress,
			final String username, final String password, final String host,
			final String portStr, final String domain) {
		int port = XMPPPORT;

		String localDomain = domain;
		String localHost = host;

		// Set canceled is false when each login start;
		canceled = false;

		// Get domain
		if (localDomain == null) {
			localDomain = username.substring(username.indexOf("@") + 1);
			// System.out.println("Domain:" + domain);
		}

		// Get port from portStr
		if (portStr != null) {
			port = Integer.parseInt(portStr);
			// System.out.println("Port:" + port);
		}

		// Get host
		if (localHost == null) {
			if (username.endsWith("gmail.com")) {
				localHost = "talk.google.com";
			} else if (username.endsWith("xiaonei.com")) {
				localHost = "talk.xiaonei.com";
			} else {
				// host = "xmpp.oscar.aol.com";
				localHost = "talk.jabber.org";
			}
			System.out.println("Host:" + localHost);
		}

		ConnectionConfiguration config = new ConnectionConfiguration(localHost,
				port, localDomain);

		// set true for debug
		// config.setDebuggerEnabled(true);

		// Create new Xmpp connection with the Gtalk configuration
		connection = new XMPPConnection(config);

		// Connected to server.
		try {
			// System.out.println("start to connect");
			connection.connect();
		} catch (XMPPException e) {
			// System.out.println("Connect failed,and canceled:" +
			// canceled);
			if (canceled) {
				return false;
			}
			/*
			 * int re = JOptionPane.showConfirmDialog(progress.window, "Can't
			 * connect to Server\nReconnect?", "Reconnecting",
			 * JOptionPane.OK_CANCEL_OPTION);
			 */

			progress.append("Failed");
			return false;
		}

		// try to login.
		try {
			// System.out.println("If canceled after connected to server
			// success:" + canceled);
			if (canceled) {
				connection.disconnect();
				return false;
			}

			// System.out.println("connected");
			progress.append("Connected.\n\tLogin...");
			connection.login(username, password);
		} catch (Exception e) {
			// System.out.println("login failed and check whether it is
			// canceled:" + canceled);
			if (canceled) {
				connection.disconnect();
				return false;
			}

			// Or print login fail info and exit.
			progress.append("\n\tAuthen failed");
			return false;
		}
		// System.out.println("Login success and check whether it is canceled:"
		// + canceled);
		if (canceled) {
			connection.disconnect();
			return false;
		}

		// Login success.
		progress.append("Logined.\n\tInitial...");
		return true;
	}

	/**
	 * Cancel the connect.
	 */
	public static void cancel() {
		canceled = true;
	}
}
